package com.chenglai.seckill.service.impl;

import com.chenglai.seckill.dao.SeckillGoodsMapper;
import com.chenglai.seckill.dao.SeckillUserMapper;
import com.chenglai.seckill.pojo.SeckillGoods;
import com.chenglai.seckill.pojo.SeckillUser;
import com.chenglai.seckill.rabbitmq.MqServer;
import com.chenglai.seckill.service.SeckillService;
import com.rabbitmq.client.*;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 类描述：
 *
 * @Author rxh
 * @Date 2023/11/23 14:32
 */
@Service
public class SeckillServiceImpl implements SeckillService {

    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private MqServer mqServer;
    @Resource
    private SeckillGoodsMapper seckillGoodsMapper;
    @Resource
    private SeckillUserMapper seckillUserMapper;

    @Override
    public Map start(Integer seckillId, Integer userId, Integer goodsId, Integer shopId, Double price, Integer number) {
        Map<String, Object> data = new HashMap<>();
        data.put("flag", "SUCCESS");
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //判断是否重复抢购
        boolean seckillOrder = false;
        try {
            //命名规则：seckill_s_u:seckillId:userId:goodsId
            seckillOrder = (boolean) redisTemplate.opsForValue().get("seckill_s_u:" + seckillId + ":" + userId + ":" + goodsId);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (seckillOrder) {
            data.put("mag", "你已抢购过了，不能再抢了");
            return data;
        }
        //预减库存 redis锁原子性操作实现减库存
        Long stock = valueOperations.decrement("seckill_g_n:" + seckillId + ":" + goodsId, number);

        if (stock <= 0) {
            data.put("mag", "手慢了，已抢没了");
            return data;
        }

        //MQ通知下单,异步
        Map<String, Object> param = new HashMap<>();
        param.put("seckillId", seckillId);
        param.put("userId", userId);
        param.put("goodsId", goodsId);
        param.put("shopId", shopId);
        param.put("price", price);
        param.put("number", number);
        mqServer.sendSeckillMessage(data);
        data.put("mag", "抢购成功了，正在为你生成订单，请稍后......");
        return data;

    }

    @Override
    public void end(Integer seckillId) {
        //秒杀结束 清空redis相关的所有数据
        //1.清空商品与数量信息
        Example example = new Example(SeckillUser.class);
        example.createCriteria().andEqualTo("seckillId", seckillId);
        List<SeckillUser> userList = seckillUserMapper.selectByExample(example);
        userList.stream().forEach(map -> {
            redisTemplate.delete("seckill_s_u:" + seckillId + ":" + map.getUserId() + ":" + map.getGoodsId());
        });

        //2.清空商品与用户信息
        Example exam = new Example(SeckillGoods.class);
        exam.createCriteria().andEqualTo("seckillId", seckillId);
        List<SeckillGoods> list = seckillGoodsMapper.selectByExample(exam);
        list.stream().forEach(map -> {
            redisTemplate.delete("seckill_g_n:" + seckillId + ":" + map.getGoodsId());
        });
    }

  }